package com.abou.aop.exception.impl;

import javax.persistence.PersistenceException;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.dao.DataAccessException;
import com.abou.aop.exception.IExceptionTranslatorAspect;
import com.abou.connector.exception.ConnectorException;
import com.abou.manager.exception.EManagerErrorCode;
import com.abou.manager.exception.ManagerException;
import com.abou.manager.exception.TranslatedManagerException;

/**
 * The implementation class of the aspect enabling to flush the transaction
 * after each method of the business managers.
 * 
 * @author khalid
 */
@Aspect
public class ExceptionTranslatorAspectImpl implements
    IExceptionTranslatorAspect {
  
  /**
   * The logger
   */
  private static final Logger LOGGER =
      Logger.getLogger(ExceptionTranslatorAspectImpl.class);
  
  /**
   * The execution order for the aspect
   */
  private static final int ORDER = 10;
  
  /**
   * The empty constructor of the class
   */
  public ExceptionTranslatorAspectImpl() {

    super();
  }
  
  /***
   * @see com.abou.aop.exception.IExceptionTranslatorAspect#translateException(org.aspectj.lang.JoinPoint,
   *      java.lang.Exception)
   */
  @AfterThrowing(pointcut = "execution(public * com.francetelecom.malicli.mac.manager.impl.*ManagerImpl.*(..))", throwing = "ex")
  public void translateException(JoinPoint jp, Exception ex) {

    // The manager exception that will be thrown
    ManagerException mngEx = null;
    
    if (ex instanceof ManagerException) {
      
      mngEx = (ManagerException) ex;
      
    } else {
      
      EManagerErrorCode mngCode = EManagerErrorCode.UNEXPECTED;
      Object[] params = null;
      
      if (ex instanceof ConnectorException) {
        
        ConnectorException connEx = (ConnectorException) ex;
        params = connEx.getParams();
        
        if (connEx.getCode() != null) {
          
          // getting the corresponding error code
          mngCode = EManagerErrorCode.getCode(connEx.getCode());
        }
        
      } else if (ex instanceof DataAccessException
          || ex instanceof IllegalArgumentException
          || ex instanceof PersistenceException) {
        
        mngCode = EManagerErrorCode.DB_ERROR;
      }
      
      mngEx = new TranslatedManagerException(mngCode, params, ex);
    }
    
    // logging the exception
    String underlyingExMsg = "";
    
    if (ex != null) {
      
      underlyingExMsg = ex.toString();
    }
    
    LOGGER.error(mngEx.toString() + "\nUnderlying exception was : "
        + underlyingExMsg, mngEx);
    
    // throwing the exception
    throw mngEx;
  }
  
  /**
   * @see org.springframework.core.Ordered#getOrder()
   */
  public int getOrder() {

    return ORDER;
  }
}
